﻿using DoNet.Common.Const;
using DoNet.Common.Enums;
using DoNet.Common.Extensions;
using DoNet.Common.Helpers;
using DoNet.Core.Models;
using DoNet.System.IServices;
using Microsoft.Extensions.Caching.Memory;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace DoNet.Extensions.Filters
{
    /// <summary>
    /// 
    /// </summary>
    public static class SqlSugarFilter
    {
        private static IMemoryCache _cacheservice = new MemoryCache(new MemoryCacheOptions());

        /// <summary>
        /// 配置租户实体过滤器
        /// </summary>
        //public static void SetTenantEntityFilter(SqlSugarScopeProvider db)
        //{
        //    // 获取租户实体数据表集合 
        //    var dataEntityTypes = RuntimeHelper.GetAllTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.BaseType == typeof(TenantEntity));
        //    if (!dataEntityTypes.Any()) return;

        //    var tenantId = Appsettings.User?.TenantId;
        //    if (tenantId == 0 || tenantId == null) return;

        //    foreach (var dataEntityType in dataEntityTypes)
        //    {
        //        Expression<Func<TenantEntity, bool>> dynamicExpression = u => u.TenantId == tenantId;
        //        db.QueryFilter.Add(new TableFilterItem<object>(dataEntityType, dynamicExpression));
        //    }
        //}

        ///// <summary>
        ///// 配置用户机构集合过滤器
        ///// </summary>
        //public static void SetOrgEntityFilter(SqlSugarScopeProvider db)
        //{
        //    // 若仅本人数据，则直接返回
        //    if (SetDataScopeFilter(db) == (int)RoleDataScopeEnum.Self) return;

        //    var userId = Appsettings.User?.UserId;
        //    if (userId == 0 || userId == null) return;

        //    // 配置用户机构集合缓存
        //    var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:dataScope:{userId}";
        //    var orgFilter = _cacheservice.Get<ConcurrentDictionary<Type, LambdaExpression>>(cacheKey);
        //    if (orgFilter == null)
        //    {
        //        // 获取用户所属机构
        //        var orgIds = Appsettings.GetService<IOrganizeService>().GetUserOrgIdList().GetAwaiter().GetResult();
        //        if (orgIds == null || orgIds.Count == 0) return;

        //        // 获取业务实体数据表
        //        var entityTypes = RuntimeHelper.GetAllTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsSubclassOf(typeof(DataEntity)));
        //        if (!entityTypes.Any()) return;

        //        orgFilter = new ConcurrentDictionary<Type, LambdaExpression>();
        //        foreach (var entityType in entityTypes)
        //        {
        //            // 排除非当前数据库实体
        //            var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
        //            if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()))
        //                continue;

        //            var lambda = DynamicExpressionParser.ParseLambda(new[] {
        //            Expression.Parameter(entityType, "u") }, typeof(bool), $"@0.Contains(u.{nameof(DataEntity.OrganizeId)}??{default(long)})", orgIds);

        //            db.QueryFilter.AddTableFilter(entityType, lambda);
        //            orgFilter.TryAdd(entityType, lambda);
        //        }
        //        _cacheservice.Set(cacheKey, orgFilter);
        //    }
        //    else
        //    {
        //        foreach (var filter in orgFilter)
        //            db.QueryFilter.AddTableFilter(filter.Key, filter.Value);
        //    }
        //}

        ///// <summary>
        ///// 配置用户仅本人数据过滤器
        ///// </summary>
        //private static int SetDataScopeFilter(SqlSugarScopeProvider db)
        //{
        //    var maxDataScope = (int)RoleDataScopeEnum.All;

        //    var userId = Appsettings.User?.UserId;
        //    if (userId == 0 || userId == null) return maxDataScope;
        //    YuebonCacheHelper yuebonCacheHelper = new YuebonCacheHelper();
        //    // 获取用户最大数据范围---仅本人数据
        //    maxDataScope = yuebonCacheHelper.Get(CacheConst.KeyRoleMaxDataScope + userId).ToInt();
        //    if (maxDataScope != (int)RoleDataScopeEnum.Self) return maxDataScope;

        //    // 配置用户数据范围缓存
        //    //var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:dataScope:{userId}";多库切换
        //    var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:dataScope:{userId}";//通用了
        //    var dataScopeFilter = _cacheservice.Get<ConcurrentDictionary<Type, LambdaExpression>>(cacheKey);
        //    if (dataScopeFilter == null)
        //    {
        //        // 获取业务实体数据表
        //        var entityTypes = RuntimeHelper.GetAllTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.IsSubclassOf(typeof(DataEntity)));
        //        if (!entityTypes.Any()) return maxDataScope;

        //        dataScopeFilter = new ConcurrentDictionary<Type, LambdaExpression>();
        //        foreach (var entityType in entityTypes)
        //        {
        //            // 排除非当前数据库实体
        //            var tAtt = entityType.GetCustomAttribute<TenantAttribute>();
        //            if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()))
        //                continue;

        //            var lambda = DynamicExpressionParser.ParseLambda(new[] {
        //            Expression.Parameter(entityType, "u") }, typeof(bool), $"u.{nameof(DataEntity.CreatorUserId)}=@0", userId);
        //            db.QueryFilter.AddTableFilter(entityType, lambda);
        //            dataScopeFilter.TryAdd(entityType, lambda);
        //        }
        //        _cacheservice.Set(cacheKey, dataScopeFilter);
        //    }
        //    else
        //    {
        //        foreach (var filter in dataScopeFilter)
        //            db.QueryFilter.AddTableFilter(filter.Key, filter.Value);
        //    }
        //    return maxDataScope;
        //}

        /// <summary>
        /// 配置自定义过滤器
        /// </summary>
        public static void SetCustomEntityFilter(SqlSugarScopeProvider db)
        {
            // 配置自定义缓存
            var cacheKey = $"db:{db.CurrentConnectionConfig.ConfigId}:custom";
            var tableFilterItemList = _cacheservice.Get<List<TableFilterItem<object>>>(cacheKey);
            if (tableFilterItemList == null)
            {
                // 获取自定义实体过滤器
                var entityFilterTypes = RuntimeHelper.GetAllTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass
                    && u.GetInterfaces().Any(i => i.HasImplementedRawGeneric(typeof(IEntityFilter))));
                if (!entityFilterTypes.Any()) return;

                var tableFilterItems = new List<TableFilterItem<object>>();
                foreach (var entityFilter in entityFilterTypes)
                {
                    var instance = Activator.CreateInstance(entityFilter);

                    IEnumerable<object>? entityFilters = null;
                    var entityFilterMethod = entityFilter.GetMethod("AddEntityFilter");
                    if(entityFilterMethod!= null)
                    {
                        var obj = entityFilterMethod.Invoke(instance, null);
                        if (obj != null)
                        { 
                            entityFilters = ((IList)obj).Cast<object>();
                        }
                    }
                    if (entityFilters == null) continue;

                    foreach (var u in entityFilters)
                    {
                        var tableFilterItem = (TableFilterItem<object>)u;
                        var entityType = tableFilterItem.GetType().GetProperty("type", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(tableFilterItem, null) as Type;
                        // 排除非当前数据库实体
                        var tAtt = entityType?.GetCustomAttribute<TenantAttribute>();
                        //if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()) ||
                        //(tAtt == null && db.CurrentConnectionConfig.ConfigId.ToString() != SqlSugarConst.MainConfigId))
                        if ((tAtt != null && db.CurrentConnectionConfig.ConfigId.ToString() != tAtt.configId.ToString()))
                            return;

                        tableFilterItems.Add(tableFilterItem);
                        db.QueryFilter.Add(tableFilterItem);
                    }
                }
                _cacheservice.Set(cacheKey, tableFilterItems);
            }
            else
            {
                tableFilterItemList.ForEach(u =>
                {
                    db.QueryFilter.Add(u);
                });
            }
        }
    }
    /// <summary>
    /// 自定义实体过滤器接口
    /// </summary>
    public interface IEntityFilter
    {
        /// <summary>
        /// 实体过滤器
        /// </summary>
        /// <returns></returns>
        IEnumerable<TableFilterItem<object>> AddEntityFilter();
    }
}
